package br.com.unirio.formula1.servico;

import java.util.HashMap;
import java.util.Map;

import br.com.unirio.formula1.modelo.Corrida;
import br.com.unirio.formula1.modelo.Equipe;
import br.com.unirio.formula1.modelo.Resultado;

/**
 * Classe que representa um colocado de uma Classificacao Geral de Equipes ({@link ClassificacaoEquipe}).
 * E composta pela posicao do colocado, a equipe representada, seu total de pontos e dois mapeamentos :
 * 
 * historicoDePosicoesDaEquipe - Mapeia a quantidade de vezes que uma equipe obteve uma determinada posicao
 * <Posicao,Quantidade>
 * Este mapeamento e necessario para a aplicacao de criterios de desempate entre colocados.
 * 
 * historicoDePontosEmCorridasDaEquipe - Mapeia os pontos que o colocado obteve em determinada corrida <Corrida,Pontos>
 * Este mapeamento e necessario para a exibicao dos pontos por corrida do colocado. Fatalmente a soma de todos os values
 * desse mapeamento deve ser igual ao total de pontos do colocado.
 * 
 * 
 * @author Victor
 * 
 */
public class ColocacaoEquipe implements Comparable<ColocacaoEquipe>
{

    private int posicao;
    private Equipe equipe;
    private double totalPontos;
    private Map<Integer, Integer> historicoDePosicoesDaEquipe;
    private Map<Corrida, Double> historicoDePontosEmCorridasDaEquipe;

    public ColocacaoEquipe(Equipe equipe, int quantidadePilotos)
    {

	this.equipe = equipe;
	historicoDePosicoesDaEquipe = new HashMap<Integer, Integer>();
	historicoDePontosEmCorridasDaEquipe = new HashMap<Corrida, Double>();
	this.posicao = 0;
	totalPontos = 0;

	// inicializacao com pontuacao zero em todas as posicoes possiveis que um piloto possa ter, ou seja, quais
	// posicoes uma equipe pode ter adquirido
	for (int i = 1; i <= quantidadePilotos; i++)
	{
	    historicoDePosicoesDaEquipe.put(i, 0);
	}

    }

    public double getPontosEmCorrida(Corrida c)
    {
	Double pontos = historicoDePontosEmCorridasDaEquipe.get(c);
	if (pontos == null)
	    return 0;
	else
	    return pontos;

    }

    public double getPontosEmCorrida(int idCorrida)
    {
	Corrida c = getCorrida(idCorrida);
	Double pontos = historicoDePontosEmCorridasDaEquipe.get(c);
	if (pontos == null)
	    return 0;
	else
	    return pontos;

    }

    public double getPontosEmCorrida(String nomeCorrida)
    {
	Corrida c = getCorrida(nomeCorrida);
	Double pontos = historicoDePontosEmCorridasDaEquipe.get(c);
	if (pontos == null)
	    return 0;
	else
	    return pontos;

    }

    private Corrida getCorrida(String nome)
    {
	for (Corrida corrida : historicoDePontosEmCorridasDaEquipe.keySet())
	{
	    if (corrida.getNome().equals(nome))
		return corrida;
	}
	return null;
    }

    private Corrida getCorrida(int idCorrida)
    {
	for (Corrida corrida : historicoDePontosEmCorridasDaEquipe.keySet())
	{
	    if (corrida.getId() == idCorrida)
		return corrida;
	}
	return null;
    }

    public int getPosicao()
    {
	return posicao;
    }

    public void setPosicao(int posicao)
    {
	this.posicao = posicao;
    }

    public Map<Integer, Integer> getHistoricoPosicoesEquipe()
    {
	return historicoDePosicoesDaEquipe;
    }

    public void setHistoricoPosicoesEquipe(Map<Integer, Integer> historicoPosicoesEquipe)
    {
	this.historicoDePosicoesDaEquipe = historicoPosicoesEquipe;
    }

    public Map<Corrida, Double> getPontosCorridas()
    {
	return historicoDePontosEmCorridasDaEquipe;
    }

    public void setPontosCorridas(Map<Corrida, Double> pontosCorridas)
    {
	this.historicoDePontosEmCorridasDaEquipe = pontosCorridas;
    }

    public double getTotalPontos()
    {
	return totalPontos;
    }

    public void setTotalPontos(double pontos)
    {
	this.totalPontos = pontos;
    }

    /**
     * Metodo que serve para a construcao passo a passo do HashMap do colocado
     * 
     * 
     * @param resultado
     */
    public void addResultado(Resultado resultado)
    {
	double pontosDaEquipe = resultado.getPontos(equipe);
	totalPontos += pontosDaEquipe;
	historicoDePontosEmCorridasDaEquipe.put(resultado.getCorrida(), pontosDaEquipe);

	// incremento no historico de posicoes da equipe com as posicoes que a equipe conseguiu no dado resultado
	if (!resultado.getPosicoesEquipe(equipe).isEmpty())
	{
	    for (Integer posicao : resultado.getPosicoesEquipe(equipe))
	    {
		int numeroPosicoesAnterior = historicoDePosicoesDaEquipe.get(posicao);
		historicoDePosicoesDaEquipe.put(posicao, ++numeroPosicoesAnterior);
	    }
	}

    }

    public int getQuantidadePosicoes(int i)
    {
	return historicoDePosicoesDaEquipe.get(i);
    }

    public Equipe getEquipe()
    {
	return equipe;
    }

    public void setEquipe(Equipe equipe)
    {
	this.equipe = equipe;
    }

    public int compareTo(ColocacaoEquipe o)
    {
	if (o.getPosicao() == this.posicao)
	    return 0;
	if (o.getPosicao() > this.posicao)
	    return -1;
	return 1;
    }

}
